package com.cmic.rcs.emoji.controller.app;

import com.cmic.origin.DataEncryptUtil;
import com.cmic.rcs.emoji.common.Constant;
import com.cmic.rcs.emoji.common.UserContext;

import com.cmic.rcs.emoji.entity.dto.UserDto;
import com.cmic.rcs.emoji.entity.pojo.TEnterpriseMember;
import com.cmic.rcs.emoji.entity.vo.AppLoginResponse;
import com.cmic.rcs.emoji.mapper.TEnterpriseMemberMapper;
import com.cmic.rcs.enhance.message.g5.core.common.Response;
import com.cmic.rcs.enhance.message.g5.core.common.ResponseData;
import com.cmic.rcs.enhance.message.g5.core.common.ReturnCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;

/**
 * APP端登录控制器
 *
 * @author 孙高明
 * @since 2025-10-14
 */
@RestController
@RequestMapping("/api/app")
@Slf4j
public class AppLoginController {

    @Autowired
    private TEnterpriseMemberMapper enterpriseMemberMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private DataEncryptUtil dataEncryptUtil;

    // Redis键前缀
    private static final String REDIS_APP_LOGIN_KEY_PREFIX = Constant.REDIS_KEY_PREFIX + ":app:login:";
    // 会话过期时间（30分钟）
    private static final long SESSION_EXPIRE_TIME_SECONDS = 30 * 60;

    /**
     * APP端授权登录接口
     *
     * @return 登录结果
     */
    @PostMapping("/login")
    public Response authorizeLogin() {
        log.info("开始处理APP端授权登录请求");
        try {
            // 从请求头获取accessToken（由TokenInterceptor统一处理验证）
            // 这里假设TokenInterceptor已经验证了token并将用户信息存入UserContext
            // 从UserContext获取用户信息（用户名即为手机号）
            String phoneNumber = getCurrentUserPhoneNumber();
            if (phoneNumber == null || !phoneNumber.matches("^\\d{11}$")) {
                log.warn("手机号格式错误或未获取到: {}", phoneNumber);
                return ResponseData.Error(ReturnCodeEnum.MVC_EXCEPTION, "手机号格式错误");
            }

            // 手机号加密
            String encryptedPhone = dataEncryptUtil.encrypt(phoneNumber);
            log.info("验证用户登录权限，手机号加密后: {}", encryptedPhone);

            // 根据手机号查询该手机号对应的用户信息
            TEnterpriseMember member =  enterpriseMemberMapper.selectByEncryptedPhone(encryptedPhone);


            if (StringUtils.isEmpty( member)) {
                log.warn("用户无登录权限: {}", phoneNumber);
                return ResponseData.Error(ReturnCodeEnum.LOGIN_FAILED, "无权限，请联系管理员添加权限");
            }

            // 生成唯一的sessionId作为登录标识
            String sessionId = UUID.randomUUID().toString().replace("-", "");

            // 构建Redis键
            String phoneKey = REDIS_APP_LOGIN_KEY_PREFIX + phoneNumber;
            String sessionKey = REDIS_APP_LOGIN_KEY_PREFIX + "session:" + sessionId;

            // 检查是否已存在登录信息（账号互踢）
            String oldSessionId = (String) redisTemplate.opsForValue().get(phoneKey);
            if (StringUtils.hasText(oldSessionId)) {
                log.info("账号[{}]在其他地方登录，执行账号互踢", "******" + phoneNumber.substring(6));
                // 删除旧会话的session信息
                redisTemplate.delete(REDIS_APP_LOGIN_KEY_PREFIX + "session:" + oldSessionId);
            }

            // 存储手机号与sessionId的映射关系
            redisTemplate.opsForValue().set(phoneKey, sessionId, SESSION_EXPIRE_TIME_SECONDS, TimeUnit.SECONDS);

            // 存储用户会话信息
            redisTemplate.opsForValue().set(sessionKey, phoneNumber, SESSION_EXPIRE_TIME_SECONDS, TimeUnit.SECONDS);

            AppLoginResponse response = new AppLoginResponse();
            response.setCode("200");
            response.setPhoneNumber(phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7)); // 脱敏处理
            response.setSessionId(sessionId); // 返回sessionId给前端
            response.setHasPermission(true);
            response.setMessage("登录成功");
            response.setExpireTime(SESSION_EXPIRE_TIME_SECONDS); // 返回过期时间

            //更新登录信息
            member.setLastLoginTime(LocalDateTime.now());
            member.setAppLoginCount(member.getAppLoginCount() + 1);
            enterpriseMemberMapper.updateById(member);

            log.info("APP端授权登录成功: {}", "******" + phoneNumber.substring(6));
            return ResponseData.OK(response);
        } catch (Exception e) {
            log.error("APP端授权登录失败: {}", e.getMessage());
            return ResponseData.Error(ReturnCodeEnum.LOGIN_FAILED, "登录失败，请重试");
        }
    }




    /**
     * 从当前上下文获取用户手机号
     */
    private String getCurrentUserPhoneNumber() {
        try {
            // 从UserContext获取当前用户信息
            UserDto userDto = UserContext.getUserDto();
            if (userDto != null && userDto.getUsername() != null) {
                log.info("从UserContext获取到用户信息，用户名(手机号): {}", userDto.getUsername());
                return userDto.getUsername();
            }
            log.warn("未从UserContext获取到用户信息");
        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * APP端退出登录
     *
     * @return 退出结果
     */
    @PostMapping("/logout")
    public Response logout() {
        try {
            // 从UserContext获取用户信息
            String phoneNumber = getCurrentUserPhoneNumber();
            if (StringUtils.hasText(phoneNumber)) {
                // 获取并删除session信息
                String phoneKey = REDIS_APP_LOGIN_KEY_PREFIX + phoneNumber;
                String sessionId = (String) redisTemplate.opsForValue().get(phoneKey);
                if (StringUtils.hasText(sessionId)) {
                    redisTemplate.delete(REDIS_APP_LOGIN_KEY_PREFIX + "session:" + sessionId);
                }
                // 删除手机号对应的登录信息
                redisTemplate.delete(phoneKey);

                log.info("用户[{}]退出登录", "******" + phoneNumber.substring(6));
            }
            return ResponseData.OK("退出成功");
        } catch (Exception e) {
            log.error("退出登录失败: {}", e.getMessage());
            return ResponseData.Error(ReturnCodeEnum.LOGIN_FAILED, "退出失败，请重试");
        }
    }

}